/*
 * RunComponent.java
 *
 * Created on March 7, 2007, 12:25 PM
 *
 * (C) R. Alexander Milowski alex@milowski.com
 */

package org.infoset.component.library;

import java.io.File;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import org.infoset.component.Component;
import org.infoset.component.ComponentDefinition;
import org.infoset.xml.Document;
import org.infoset.xml.DocumentLoader;
import org.infoset.xml.Infoset;
import org.infoset.xml.InfosetFactory;
import org.infoset.xml.Name;
import org.infoset.xml.NamespaceScope;
import org.infoset.xml.XMLException;
import org.infoset.xml.sax.SAXDocumentLoader;
import org.infoset.xml.util.DocumentDestination;
import org.infoset.xml.util.DocumentSource;
import org.infoset.xml.util.WriterItemDestination;

/**
 *
 * @author R. Alexander Milowski
 */
public class RunComponent {
   
   /** Creates a new instance of RunComponent */
   public RunComponent() {
   }
   
   public static void main(String [] args) {
      if (args.length<1) {
         System.err.println("Usage: RunComponent name { port=file ... }");
         System.exit(1);
      }
      try {
         Name componentName = Name.create(args[0]);
         ComponentDefinition def = Library.getRegistry().get(componentName);
         
         final DocumentLoader docLoader = new SAXDocumentLoader();
         Component c = def.newInstance();
         c.init(new Component.Context() {

            public Logger getLog() {
               return Logger.getAnonymousLogger();
            }

            public NamespaceScope getNamespaceScope() {
               return NamespaceScope.getDefaultScope();
            }

            public Object getParameter(Name name) {
               return null;
            }
            
            public Collection<Name> getParameterNames() {
               Collection<Name> names = Collections.emptySet();
               return names;
            }
            
            public URI getBaseURI() {
               return new File(".").toURI();
            }

            public DocumentLoader getDocumentLoader() {
               return docLoader;
            }

            public Infoset getInfoset() {
               return InfosetFactory.getDefaultInfoset();
            }
         });
         
         Collection<Name> inputPorts = def.getInputs();
         for (int i=1; i<args.length; i++) {
            int equals = args[i].indexOf('=');
            if (equals<1) {
               System.err.println("Invalid port binding: "+args[i]);
               System.exit(1);
            }
            String namePart = args[i].substring(0,equals);
            String filePart = args[i].substring(equals+1);
            Name portName = Name.create(namePart);
            if (!inputPorts.contains(portName)) {
               System.err.println("Port name "+portName+" is not specified on "+componentName);
               System.err.println("Inputs available are:");
               for (Name name : inputPorts) {
                  System.err.println(name.toString());
               }
               System.exit(1);
            }
            File file = new File(filePart);
            c.bindResource(portName,file.toURI());
         }
         
         Collection<Name> outputPorts = def.getOutputs();
         final Map<Name,Document> output = new HashMap<Name,Document>();
         if (outputPorts.size()==1) {
            c.bindOutputPort(outputPorts.iterator().next(),new WriterItemDestination(System.out));
         } else {
            for (Name name : outputPorts) {
               final Name currentPort = name;
               c.bindOutputPort(name,new DocumentDestination() {
                  public void onDocument() {
                     output.put(currentPort,getDocument());
                  }
               });
            }
         }
         
         c.onStart();
         
         c.onEnd();
         
         for (Name name : output.keySet()) {
            System.out.println("Port: "+name);
            DocumentSource.generate(output.get(name),false,new WriterItemDestination(System.out));
         }
      } catch (XMLException ex) {
         ex.printStackTrace();
      }
      
   }
   
}
